package com.xt.tea.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;


/**
 * 树工具类
 */
public class TreeUtil<T,K>{
    private final List<T> list;
    private final Function<? super T, ? extends K> idFunc;
    private final Function<? super T, ? extends K> pidFunc;
    private final TreeChildConsumer<T> setChildren;

    /**
     *
     * @param list        需要转换的list数据
     * @param idFunc      节点的id
     * @param pidFunc     节点的父id
     * @param setChildren 注入子节点的方法
     */
    public TreeUtil(List<T> list,
                             Function<? super T, ? extends K> idFunc,
                             Function<? super T, ? extends K> pidFunc,
                             TreeChildConsumer<T> setChildren) {
        this.list = list;
        this.idFunc = idFunc;
        this.pidFunc = pidFunc;
        this.setChildren = setChildren;
    }

    /**
     * 开始构建节点
     *
     * @return list 所有根节点的集合
     */
    public List<T> build() {
        List<T> data = this.list;
        if (data.isEmpty()) {
            return null;
        }
        List<T> rootList = new ArrayList<>();
        for (T root : data) {
            if (data.stream().noneMatch(item -> idFunc.apply(item).equals(pidFunc.apply(root)))) {
                rootList.add(buildChild(root));
            }
        }
        return rootList;
    }

    /**
     * 使用递归开始构建子节点
     *
     * @param parent 父节点
     * @return T 构建好当前节点的所有子节点
     */
    protected T buildChild(T parent) {
        List<T> children = new ArrayList<>();
        for (T t : list) {
            if (idFunc.apply(parent).equals(pidFunc.apply(t))) {
                children.add(buildChild(t));
            }
        }
        // 找到所有子节点后将其注入到父节点
        setChildren.accept(parent, children);
        return parent;
    }

    @FunctionalInterface
    public interface TreeChildConsumer<T> {
        void accept(T t, List<T> tList);
    }


}
